package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.PayBaseInfo;
import com.ruoyi.common.enums.BusinessEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.assembler.PayAssembler;
import com.ruoyi.system.domain.PaymentRecord;
import com.ruoyi.system.domain.Product;
import com.ruoyi.system.domain.RechargeRecord;
import com.ruoyi.system.domain.vo.ClientInfoVo;
import com.ruoyi.system.domain.vo.PaySubmitVo;
import com.ruoyi.system.mapper.PaymentRecordMapper;
import com.ruoyi.system.service.IPaymentRecordService;
import com.ruoyi.system.service.IProductService;
import com.ruoyi.system.service.IRechargeRecordService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class PaymentRecordServiceImpl extends ServiceImpl<PaymentRecordMapper, PaymentRecord> implements IPaymentRecordService {

    @Autowired
    private PayBaseInfo payBaseInfo;

    @Autowired
    private IProductService productService;

    @Autowired
    private IRechargeRecordService rechargeRecordService;

    @Override
    @Transactional
    public PaymentRecord createRecord(PaymentRecord record) {
        Product product = productService.getById(record.getProductId());
        Optional.ofNullable(product).orElseThrow(() -> new ServiceException("无效商品"));
        if (ObjectUtils.equals(product.getStatus(), 0)) {
            new ServiceException(product.getName() + "：已下架");
        }
        if (Objects.isNull(product.getOriginalPrice())) {
            throw new ServiceException("该商品未设置价格");
        }
        if (Objects.isNull(product.getStock()) || NumberUtil.compare(0, product.getStock()) == 0) {
            throw new ServiceException("该商品已售罄");
        }
        Optional.ofNullable(record.getCount()).orElseThrow(() -> new ServiceException("请填写购买数量"));
        Optional.ofNullable(StrUtil.emptyToNull(record.getBuyer())).orElseThrow(() -> new ServiceException("请输入邮箱"));
        Optional.ofNullable(StrUtil.emptyToNull(record.getDevice())).orElseThrow(() -> new ServiceException("未传入设备类型"));
        Optional.ofNullable(StrUtil.emptyToNull(record.getType())).orElseThrow(() -> new ServiceException("未传入支付方式"));

        PayBaseInfo payBaseInfoEntity = payBaseInfo.getPayBaseInfo();
        record.setCreateTime(new Date());
        //Boolean recharge = BusinessEnum.ProductType.RECHARGE.getCode().equals(product.getType());
        record.setPrice(record.getPrice());
        record.setSignType(payBaseInfoEntity.getSign_type());
        record.setPayStatus("1");
        record.setProductCnName(product.getName());
        record.setTotalValue(record.getTotalValue());
        if (NumberUtil.compare(record.getTotalValue(), 0.01) < 0) {
            throw new ServiceException("金额不合法");
        }
        this.save(record);
        return record;
    }

    @Override
    @Transactional
    public PaymentRecord createRecordByPaySubmit(PaySubmitVo paySubmitVo, HttpServletRequest request) {
        PaymentRecord record = PayAssembler.INSTANCE.convertPaySubmitVoToPaymentRecord(paySubmitVo);
        // 判断商品类型 如果是需要重置的业务重写计算金额
        Product product = productService.getById(paySubmitVo.getProductId());
        Optional.ofNullable(product).orElseThrow(() -> new ServiceException("无效商品"));
        if (ObjectUtils.equals(product.getStatus(), 0)) {
            new ServiceException(product.getName() + "：已下架");
        }
        //@todo 取消商品代充业务，由客服处理
        /*Boolean recharge = BusinessEnum.ProductType.RECHARGE.getCode().equals(product.getType());
        List<RechargeRecord> rechargeRecords = null;
        if (recharge) {
            if (CollectionUtil.isEmpty(paySubmitVo.getClientInfoVos())) {
                throw new ServiceException("请填写需要充值的信息");
            }
            List<ClientInfoVo> infoVos = paySubmitVo.getClientInfoVos().parallelStream().filter(
                    info -> StrUtil.isNotBlank(info.getAccount())
                            && StrUtil.isNotBlank(info.getPassword())
                            && Objects.nonNull(info.getAmount())
            ).collect(Collectors.toList());

            rechargeRecords = BeanUtil.copyToList(infoVos, RechargeRecord.class);

            // 计算总金额
            double reduce = rechargeRecords.stream()
                    .mapToDouble(RechargeRecord::getAmount)
                    .reduce(0, Double::sum);

            record.setCount(rechargeRecords.size());
            record.setTotalValue(reduce);
            record.setPrice(NumberUtil.div(reduce, rechargeRecords.size()));
        }*/
        record.setPrice(product.getPrice());
        record.setTotalValue(NumberUtil.mul((Number) record.getCount(), (Number) product.getPrice())
                        .setScale(2, RoundingMode.HALF_UP)
                        .doubleValue());
        String ip = IpUtils.getIpAddr(request);
        record.setClientip(ip);
        this.createRecord(record);

        /*if (recharge) {
              // 填充订单ID
            Optional.ofNullable(rechargeRecords).ifPresent(records -> {
                records.forEach((r -> r.setPaymentRecordId(record.getId())));
                rechargeRecordService.saveBatch(records);
            });
        }*/
        return record;
    }

}
